home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / checkbox / component.py < prev    next >
Text File  |  2009-11-05  |  7KB  |  185 lines

  1. #
  2. # This file is part of Checkbox.
  3. #
  4. # Copyright 2008 Canonical Ltd.
  5. #
  6. # Checkbox is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Checkbox is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import os
  20. import re
  21. import itertools
  22. import logging
  23. import posixpath
  24.  
  25. from checkbox.lib.cache import cache
  26. from checkbox.lib.path import path_expand_recursive
  27.  
  28. from checkbox.properties import List, String
  29. from checkbox.variables import get_variables
  30.  
  31.  
  32. class ComponentSection(object):
  33.     """
  34.     Component section which is essentially a container of modules. These
  35.     map to the modules referenced in the configuration passed as argument
  36.     to the constructor.
  37.     """
  38.  
  39.     modules = List(type=String())
  40.     whitelist = List(type=String(), default_factory=lambda:"")
  41.     blacklist = List(type=String(), default_factory=lambda:"")
  42.  
  43.     def __init__(self, config, name):
  44.         """
  45.         Constructor which takes a configuration instance and name as
  46.         argument. The former is expected to contain modules.
  47.         """
  48.         self._config = config
  49.         self.name = name
  50.  
  51.         self.modules = config.modules
  52.         self.whitelist = config.get("whitelist")
  53.         self.blacklist = config.get("blacklist")
  54.  
  55.     @cache
  56.     def get_names(self):
  57.         """
  58.         Get all the module names contained in the filenames or directories
  59.         for this section.
  60.         """
  61.         whitelist_patterns = [re.compile(r"^%s$" % r) for r in self.whitelist]
  62.         blacklist_patterns = [re.compile(r"^%s$" % r) for r in self.blacklist]
  63.  
  64.         # Determine names
  65.         names = set()
  66.         filenames = itertools.chain(*[path_expand_recursive(m)
  67.             for m in self.modules])
  68.         for filename in filenames:
  69.             name = posixpath.basename(filename)
  70.             if not name.endswith(".py") or name == "__init__.py":
  71.                 # Ignore silently
  72.                 continue
  73.  
  74.             name = name.replace(".py", "")
  75.             if whitelist_patterns:
  76.                 if not [name for p in whitelist_patterns if p.match(name)]:
  77.                     logging.info("Not whitelisted module: %s", name)
  78.                     continue
  79.             elif blacklist_patterns:
  80.                 if [name for p in blacklist_patterns if p.match(name)]:
  81.                     logging.info("Blacklisted module: %s", name)
  82.                     continue
  83.  
  84.             names.add(name)
  85.  
  86.         return list(names)
  87.  
  88.     def has_module(self, name):
  89.         """
  90.         Check if the given name is in this section.
  91.         """
  92.         return name in self.get_names()
  93.  
  94.     def load_module(self, name):
  95.         """
  96.         Load a single module by name from this section.
  97.         """
  98.         logging.info("Loading module %s from section %s",
  99.             name, self.name)
  100.  
  101.         if not self.has_module(name):
  102.             raise Exception, "No such such module: %s" % name
  103.  
  104.         filenames = itertools.chain(*[path_expand_recursive(m)
  105.             for m in self.modules])
  106.         for filename in filenames:
  107.             if filename.endswith(".py") and posixpath.exists(filename):
  108.                 basename = posixpath.basename(filename)
  109.                 basename = basename.replace(".py", "")
  110.                 if basename == name:
  111.                     globals = {}
  112.                     exec open(filename) in globals
  113.                     if "factory" not in globals:
  114.                         raise Exception, "Variable 'factory' not found in: %s" \
  115.                             % filename
  116.  
  117.                     module = globals["factory"]()
  118.                     module.__module__ = name
  119.  
  120.                     config_name = "/".join([self.name, name])
  121.                     config = self._config.parent.get_section(config_name)
  122.  
  123.                     # Set configuration values
  124.                     variables = get_variables(module)
  125.                     environ = dict([(k.lower(), v) for k, v in os.environ.items()])
  126.                     for attribute, variable in variables.iteritems():
  127.                         if config and attribute.name in config:
  128.                             value = config.get(attribute.name)
  129.                             variable.set(value)
  130.                         else:
  131.                             value = variable.get()
  132.                             if isinstance(value, basestring):
  133.                                 value = value % environ
  134.                                 variable.set(value)
  135.                             elif isinstance(value, list):
  136.                                 value = [v % environ for v in value]
  137.                                 variable.set(value)
  138.  
  139.                     # Check required attributes
  140.                     for attribute, variable in variables.iteritems():
  141.                         value = variable.get()
  142.                         if value is None and variable._required:
  143.                             raise Exception, "Configuration '%s' missing " \
  144.                                 "required attribute: %s" \
  145.                                 % (config_name, attribute.name)
  146.  
  147.                     return module
  148.  
  149.         raise Exception, "Failed to find module '%s' in: %s" % (name, filenames)
  150.  
  151.     def load_modules(self):
  152.         """
  153.         Load all modules contained in this section.
  154.         """
  155.         modules = []
  156.         for name in self.get_names():
  157.             module = self.load_module(name)
  158.             modules.append(module)
  159.  
  160.         return modules
  161.  
  162.  
  163. class ComponentManager(object):
  164.     """
  165.     Component manager which is essentially a container of sections.
  166.     """
  167.  
  168.     _section_factory = ComponentSection
  169.  
  170.     def __init__(self, config):
  171.         """
  172.         Constructor which takes a configuration instance as argument. This
  173.         will be used to load sections by name.
  174.         """
  175.         self._config = config
  176.  
  177.     def load_section(self, name):
  178.         """
  179.         Load a section by name which must correspond to a module in the
  180.         configuration instance pased as argument to the constructor.
  181.         """
  182.         logging.info("Loading component section %s", name)
  183.         config = self._config.get_section(name)
  184.         return self._section_factory(config, name)
  185.